//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics.Contracts;

namespace OpenLS.Spreadsheet
{
    partial class Worksheet
    {
        public void FreezePanes(int? rowIndex, int? columnIndex)
        {
            bool wantsDelete = rowIndex == null && columnIndex == null;
            if (wantsDelete)
            {
                if (View.Pane != null && View.Pane.State == PaneState.FrozenSplit)
                {
                    SetPaneState(PaneState.Split);
                    return;
                }
                else
                    SetPaneState(null);
            }
            else
            {
                SetPaneState(PaneState.Frozen);
                View.Pane.ColumnCount = columnIndex;
                View.Pane.RowCount = rowIndex;
            }
            //\\ TopLeftPane
            FreezeOrSplit(rowIndex, columnIndex);
        }

        /// <summary>
        /// Split the worksheet 
        /// </summary>
        /// <param name="rowIndex">The row index where to split</param>
        /// <param name="columnIndex">The column index where to split</param>
        public void SplitPanes(int? rowIndex, int? columnIndex)
        {
            bool wantsDelete = rowIndex == null && columnIndex == null;
            if (wantsDelete)
            {
                SetPaneState(null);
            }
            else
            {
                SetPaneState(PaneState.Split);
                View.Pane.ColumnCount = columnIndex;
                View.Pane.RowCount = rowIndex;
            }
            //\\ TopLeftPane
            //\\ View.Pane.State = PaneState.Frozen;

            FreezeOrSplit(rowIndex, columnIndex);
            if (View.Pane != null)
            {
                if (TopLeftPane.DesiredWidth != null)
                    View.Pane.Width = TopLeftPane.DesiredWidth.Value;
                if (TopLeftPane.DesiredHeight != null)
                    View.Pane.Height = TopLeftPane.DesiredHeight.Value;

            }
        }

        private void SetPaneState(PaneState? state)
        {
            if (state == null)
            {
                if (View.Pane == null)
                    return;
                switch (View.Pane.State)
                {
                    case PaneState.Frozen:
                    case PaneState.Split:
                        View.Pane = null;
                        break;
                    case PaneState.FrozenSplit:
                        View.Pane = null; //\\ PaneState.Split;
                        break;
                    default:
                        throw new NotSupportedException();
                }
                return;
            }
            if (View.Pane == null)
            {
                View.Pane = new Pane { State = state.Value };
            }
            switch (state.Value)
            {
                case PaneState.Split:
                    switch (View.Pane.State)
                    {
                        case PaneState.Split:
                        case PaneState.FrozenSplit:
                            View.Pane.State = PaneState.Split;
                            break;
                        case PaneState.Frozen:
                            View.Pane.State = PaneState.Split;
                            break;
                    }
                    break;

                case PaneState.Frozen:
                    switch (View.Pane.State)
                    {
                        case PaneState.Frozen:
                        case PaneState.FrozenSplit:
                            break;
                        case PaneState.Split:
                            View.Pane.State = PaneState.FrozenSplit;
                            break;
                    }
                    break;
                default: throw new NotSupportedException();
            }
        }


        private void FreezeOrSplit(int? rowIndex, int? columnIndex)
        {
            if (rowIndex == null)
            {
                BottomLeftPane = null;
                BottomRightPane = null;
            }
            else
            {
                if (BottomLeftPane == null)
                    BottomLeftPane = new WorksheetPane(this);
                BottomLeftPane.Top = rowIndex.Value;
                BottomLeftPane.Left = TopLeftPane.Left;
            }
            if (columnIndex == null)
            {
                TopRightPane = null;
                BottomRightPane = null;
            }
            else
            {
                if (TopRightPane == null)
                    TopRightPane = new WorksheetPane(this);
                TopRightPane.Left = columnIndex.Value;
                TopRightPane.Top = TopLeftPane.Top;
            }
            if (rowIndex != null && columnIndex != null)
            {
                if (BottomRightPane == null)
                    BottomRightPane = new WorksheetPane(this);
                BottomRightPane.Left = TopRightPane.Left;
                BottomRightPane.Top = BottomLeftPane.Top;
            }
            if (TopLeftPane == null)
            TopLeftPane = new WorksheetPane(this);
            TopLeftPane.NotifyPropertyChanged("DesiredWidth");
            TopLeftPane.NotifyPropertyChanged("DesiredHeight");
            NotifyPropertyChanged("TopLeftPane");
        }

        internal WorksheetPane GetPaneFor(Cell activeCell)
        {
            Contract.Requires(activeCell != null);
            Contract.Ensures(Contract.Result<WorksheetPane>() != null);
           // if (TopLeftPane != null && TopLeftPane.Contains2(activeCell))
             //   return TopLeftPane;
            if (TopRightPane != null)
            {
                if (activeCell.Column.Index > TopLeftPane.Right || Pane.ColumnCount.GetValueOrDefault(int.MaxValue) <= activeCell.Column.Index)
                {
                    if (BottomRightPane != null)
                    {
                        if (activeCell.Row.Index > TopLeftPane.Bottom || Pane.RowCount.GetValueOrDefault(int.MaxValue) <= activeCell.Row.Index)
                        {
                            return BottomRightPane;
                        }
                    }
                    return TopRightPane;
                }
            }
            if (BottomLeftPane != null)
                if (activeCell.Row.Index > TopLeftPane.Bottom || Pane.RowCount.GetValueOrDefault(int.MaxValue) < activeCell.Row.Index)
                    return BottomLeftPane;
            return TopLeftPane;
        }
    }
}
